package blackstar.plugin.jmxproxy;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import blackstar.agent.AgentConfig;
import blackstar.agent.jmx.AgentJMXAuthenticator;
import blackstar.agent.jmx.MBeanUtils;
import blackstar.agent.security.UserManager;
import blackstar.agent.service.ServiceFactory;
import blackstar.agent.util.IPUtil;

public class JMXRemoteProxyUtil
{
	private final static Log LOGGER = LogFactory.getLog(JMXRemoteProxyUtil.class);
	
	private final static Map ENVIROMENT = new HashMap();
	static
	{
		ENVIROMENT.put("jmx.remote.x.http.embedded.web.container.class",
				"blackstar.agent.web.AgentWebContainer");
		ENVIROMENT.put("jmx.remote.protocol.provider.class.loader",
				MBeanUtils.class.getClassLoader());
		UserManager authenticator = ServiceFactory.getUserManager();
		if (authenticator != null)
		{
			ENVIROMENT.put(JMXConnectorServer.AUTHENTICATOR,
					new AgentJMXAuthenticator(authenticator));
		}
	}

	public static JMXConnectorServer createJMXConnectorServer(String urlPath)
			throws IOException
	{
		MBeanServer server = ManagementFactory.getPlatformMBeanServer();

		return createJMXConnectorServer(urlPath, server);
	}

	public static JMXProtocol getJMXProtocol()
	{
		String ip = AgentConfig.getWebIP();
		if (isEmpty(ip))
		{
			ip = IPUtil.getLocalIP();
		} else
		{
			ip = ip.trim();
		}
		int port = AgentConfig.getWebPort();
		String protocol = AgentConfig.getProperty("agent.protocol");
		if (isEmpty(protocol))
		{
			protocol = "hessian";
		} else
		{
			protocol = protocol.trim();
		}

		return new JMXProtocol(protocol, ip, port);

	}

	public static JMXConnectorServer createJMXConnectorServer(String urlPath,
			MBeanServer server) throws MalformedURLException, IOException
	{
		JMXProtocol protocol = getJMXProtocol();
		JMXServiceURL url = new JMXServiceURL(protocol.getProtocol(), protocol
				.getHost(), protocol.getPort(), urlPath);
		JMXConnectorServer connectorServer = JMXConnectorServerFactory
				.newJMXConnectorServer(url, ENVIROMENT, server);

		LOGGER.info("CreateJMXConnectorServer[url=" + urlPath + ",server="
				+ server + "]");
		return connectorServer;
	}

	public static String getJMXProxyServiceURL(String name)
	{
		try
		{
			JMXProtocol protocol = getJMXProtocol();
			JMXServiceURL url = new JMXServiceURL(protocol.getProtocol(),
					protocol.getHost(), protocol.getPort(), "/" + name);

			return url.toString();
		} catch (MalformedURLException e)
		{
			return "";
		}
	}

	private static boolean isEmpty(String str)
	{
		return (str == null || str.trim().length() == 0);
	}
}
